#include "common.h"
#include "version.h"

#include "Engine.h"

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
		// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

	HWND hWnd;
	MSG msg = {0};
	UINT width, height;

	//it must be readed from confing file
	width = WIN32_TMP_WND_WIDTH;
	height = WIN32_TMP_WND_HEIGHT;

	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszMenuName = NULL;
	wc.style = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszClassName = TEXT(WIN32_WND_CLASS_NAME);
	wc.lpszMenuName = NULL;

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Cannot register window class", "Error!", MB_OK | MB_ICONERROR);
		return 1;
	}

	
	hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT(WIN32_WND_CLASS_NAME), TEXT(WIN32_WND_NAME), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);

	if(hWnd == NULL)
	{
		MessageBox(NULL, "Cannot create window", "Error!", MB_OK | MB_ICONERROR);
		return 1;
	}
	

	//Set data at engine init structure
	GD::_ED.hWnd = hWnd;
	GD::_ED.lpCmdLine = lpCmdLine;
	GD::_ED.nCmdShow = nCmdShow;
	GD::_ED.windowWidth = width;
	GD::_ED.windowHeight = height;

	//Start engine
	Engine::Instance().Start();	
	
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			Engine::Instance().Update();
		}
	}

	//Release resources
	Engine::Instance().Shutdown();

	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	return Engine::Instance().EngMsgProc(hWnd, msg, wParam, lParam);
}